# -*- coding: utf-8 -*-
# @File:     menulist.py
# @Author:
# @DateTime: 2025/06/04/16:41
from typing import Optional, Union, Any

from fastapi.encoders import jsonable_encoder
from sqlalchemy import or_
from sqlalchemy.orm import Session
from app.db.database import get_db
from app.models.system import Users
from app.utils import security
from app.utils.custom_response import success_response
from fastapi import APIRouter, Query, Body, Path, Depends, UploadFile, Form, File, Request
from pydantic import BaseModel, Field

from app.models.generate import MenuList
from app.utils.curd_base import ModelCRUD
from app.utils.file_storage import get_storage_file, save_storage_file, delete_storage_file

router = APIRouter()


class CRUDMenulist(ModelCRUD):
    model = MenuList

    @staticmethod
    def serializer(queryset, only: tuple = (), date_format: str = None, datetime_format: str = None,
                   time_format: str = None):
        li = list()
        for instance in queryset:
            data = instance.to_dict(only=only, date_format=date_format, datetime_format=datetime_format, time_format=time_format)
            data['image_url'] = get_storage_file(data.get('image')) if data.get('image') else None
            li.append(data)
        return li


class CreateMenuList(BaseModel):
    name: str = Field(description='名字')
    type: Optional[int] = Field(default=None, description='类型')
    image: Optional[str] = Field(default=None, description='图片')
    label: Optional[str] = Field(default=None, description='标签')
    describe: Optional[str] = Field(default=None, description='描述')
    sort: Optional[int] = Field(description='排序', default=1)
    point: Optional[int] = Field(description='点数', default=1)
    queue: Optional[str] = Field(default=None, description='队列')
    order: Optional[str] = Field(default=None, description='排序')
    input: Optional[str] = Field(default=None, description='输入')
    workflowId: Optional[str] = Field(default=None, description='工作流')
    enable: Optional[int] = Field(description='可用', default=1)


class RespMenuList(CreateMenuList):
    image_url: Optional[str] = Field(default=None, description='图片URL')


class DeleteModel(BaseModel):
    id: list[int] = Field(description='ID列表')


@router.post("/menulist", summary="新增菜单", response_model=RespMenuList, name='新增菜单')
async def create_menulist(
    *,
    db: Session = Depends(get_db),
    image: UploadFile = File(default=None),
    name: str = Form(..., description='名字'),
    type: int = Form(None, description='类型'),
    label: str = Form(None, description='标签'),
    describe: str = Form(None, description='描述'),
    sort: int = Form(1, description='排序'),
    point: int = Form(1, description='点数'),
    queue: str = Form(None, description='队列'),
    order: str = Form(None, description='排序'),
    input: str = Form(None, description='输入'),
    workflowId: str = Form(None, description='工作流'),
    enable: int = Form(1, description='可用'),

    current_user: Users = Depends(security.verify_admin_permission),
) -> Any:

    path = None
    print(image)
    if image:
        path, msg = save_storage_file(image, folder='menu')
    print(path)
    req_data = {
        'image': path,
        'name': name,
        'type': type,
        'label': label,
        'describe': describe,
        'sort': sort,
        'point': point,
        'queue': queue,
        'order': order,
        'input': input if input else "{}",
        'workflowId': workflowId,
        'enable': enable
    }
    instance = CRUDMenulist().create(db, data=CreateMenuList.validate(req_data))
    only = ('id', 'name', 'image', 'label', 'describe', 'sort', 'point', 'queue', 'order', 'input', 'workflowId')
    data = instance.to_dict(only=only)
    data['image_url'] = get_storage_file(data.get('image')) if data.get('image') else None
    return success_response(data=data)


able_filter_list = [
    {'name': 'name', 'source_filed': 'name', 'lookup_expr': 'ic', 'label': '包含名字', 'type': str, 'method': None, 'required': False},
]


@router.get("/menulist", summary="获取菜单", response_model=RespMenuList, name='获取菜单')
async def get_menulist(
    request: Request,
    *,
    db: Session = Depends(get_db),
    page: int = Query(1, description='页码', ge=1),
    page_size: int = Query(10, description='页面大小', le=50, ge=1),
    name: str = Query(None, description='名字'),
    current_user: Users = Depends(security.verify_admin_permission),
) -> Any:
    order_by_fields = ('-sort', '-id')
    crud = CRUDMenulist()
    queryset, total = crud.get_page_queryset(db, page=page, page_size=page_size, req_data=request.query_params, able_filter_list=able_filter_list, order_by_fields=order_by_fields)
    only = ('id', 'name', 'image', 'label', 'describe', 'sort', 'point', 'queue', 'order', 'input', 'workflowId', 'enable')
    items = crud.serializer(queryset, only=only)
    resp = {
        "list": items,
        'total': total
    }
    return success_response(data=resp)


@router.put("/menulist/{instance_id}", summary="修改菜单", response_model=RespMenuList, name='修改菜单')
async def edit_menulist(
    *,
    instance_id,
    db: Session = Depends(get_db),
    image: UploadFile = File(default=None),
    name: str = Form(None, description='名字'),
    type: int = Form(None, description='类型'),
    label: str = Form(None, description='标签'),
    describe: str = Form(None, description='描述'),
    sort: int = Form(1, description='排序'),
    point: int = Form(1, description='点数'),
    queue: str = Form(None, description='队列'),
    order: str = Form(None, description='排序'),
    input: str = Form(None, description='输入'),
    workflowId: str = Form(None, description='工作流'),
    enable: int = Form(1, description='可用'),

    current_user: Users = Depends(security.verify_admin_permission),
) -> Any:
    crud = CRUDMenulist()
    instance = crud.get_object(db, instance_id)
    if image:
        path, _ = save_storage_file(image, folder='menu')
        delete_storage_file(instance.image)
    else:
        path = instance.image
    req_data = {
        'image': path,
        'name': name,
        'type': type,
        'label': label,
        'describe': describe,
        'sort': sort,
        'point': point,
        'queue': queue,
        'order': order,
        'input': input if input else "{}",
        'workflowId': workflowId,
        'enable': enable
    }
    instance = crud.update(db, instance=instance, data=CreateMenuList.validate(req_data))
    only = ('id', 'name', 'image', 'label', 'describe', 'sort', 'point', 'queue', 'order', 'input', 'workflowId')
    data = instance.to_dict(only=only)
    data['image_url'] = get_storage_file(data.get('image')) if data.get('image') else None
    return success_response(data=data)


@router.delete("/menulist", summary="删除菜单", response_model=RespMenuList, name='删除菜单')
async def delete_role(
    *,
    db: Session = Depends(get_db),
    req_data: DeleteModel,
    current_user: Users = Depends(security.verify_admin_permission),
) -> Any:
    req_body = jsonable_encoder(req_data)
    id_list = req_body.get('id', [])
    queryset = db.query(MenuList).filter(MenuList.id.in_(id_list))

    for instance in queryset:
        delete_storage_file(instance.image)
    queryset.delete()
    db.commit()
    return success_response(data={})


# ----------------------------------------------------

def user_search_filter(queryset, name, value):
    return queryset.filter(or_(MenuList.name.contains(value), MenuList.label.contains(value), MenuList.describe.contains(value),))


user_able_filter_list = [
    {'name': 'search_info', 'source_filed': 'name', 'lookup_expr': 'ic', 'label': '搜索字段', 'type': str, 'method': user_search_filter, 'required': False},
    {'name': 'enable', 'source_filed': 'enable', 'lookup_expr': 'eq', 'label': 'enable', 'type': int, 'method': None, 'required': True},
]


@router.get("/get_menulist", summary="用户获取菜单", response_model=RespMenuList, name='用户获取菜单')
async def get_menulist(
    request: Request,
    *,
    db: Session = Depends(get_db),
    page: int = Query(1, description='页码', ge=1),
    page_size: int = Query(10, description='页面大小', le=50, ge=1),
    search_info: str = Query(None, description='搜索字段'),
    # current_user: Users = Depends(security.verify_access_token),
) -> Any:
    order_by_fields = ('-sort', '-id')
    crud = CRUDMenulist()
    # req_data = request.query_params
    # print(req_data)
    # setattr(req_data, 'enable', 1)
    req_data = {
        'enable': 1
    }
    if search_info:
        req_data['search_info'] = search_info

    queryset, total = crud.get_page_queryset(db, page=page, page_size=page_size, req_data=req_data, able_filter_list=user_able_filter_list, order_by_fields=order_by_fields)
    only = ('id', 'name', 'image', 'describe', 'point', 'input')
    items = crud.serializer(queryset, only=only)
    resp = {
        "list": items,
        'total': total
    }
    return success_response(data=resp)

